package com.huanf.read.batch;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.junit.jupiter.api.Test;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author: 35238
 * 功能: 批量读取表格的每一格。注意格子是什么类型，读取的时候就要用什么类型去读
 * 时间: 2023-12-22 22:13
 */
//演示xls或者xlsx都可以，我演示的是xlsx，用XSSFWorkbook、XSSFCell
public class Xlsx07ReadBatch {

    //表格的位置。为了方便写的是项目路径
    String PATH = "E:\\桌面\\Java-Ready\\conf\\Excel\\";

    @Test
    void Xls03SimpleRead() throws IOException {

        //读取表格
        FileInputStream fileInputStream = new FileInputStream(PATH + "readExcel.xlsx");

        //由于表格是xls尾缀的，所以用Workbook接口的HSSFWorkbook子实现类去读取这个表格
        Workbook workbook = new XSSFWorkbook(fileInputStream);

        //获取表格里面的数据。0表示获取第一个表。因为你表格左下角位置可能会显示多个表，例如sheet1、sheet2、sheet3
        Sheet sheet = workbook.getSheetAt(0);

        //获取第一行
        Row rowTitle = sheet.getRow(0);
        if (rowTitle != null) {
            //getPhysicalNumberOfCells获取第一行里面有多少个格子
            int cellCount = rowTitle.getPhysicalNumberOfCells();
            //获取第一行的每一个格子
            for (int cellNum=0; cellNum<cellCount; cellNum++) {
                // 获取到的cell就是第一行的每一个格子
                Cell cell = rowTitle.getCell(cellNum);
                if (cell != null) {
                    //由于第一行是字符串类型，所以这里就不使用switch-case判断了
                    String celllValue = cell.getStringCellValue();
                    System.out.print(celllValue + " | ");
                }
            }
            System.out.println();
        }

        //getPhysicalNumberOfRows获取有多少行
        int rowCount = sheet.getPhysicalNumberOfRows();
        //获取除了第一行的其它所有行。注意索引从1开始，而不是从0开始，因为0表示第一行，而第一行我们上面已经读取过了
        for (int rowNum=1; rowNum<rowCount; rowNum++) {
            Row rowData = sheet.getRow(rowNum);
            //判断获取到的行是否为空
            if (rowData != null) {//进入这个循环，表示你已经拿到了其中一行
                //getPhysicalNumberOfCells获取一行里面有多少个格子
                int cellCount = rowTitle.getPhysicalNumberOfCells();
                //获取一行的每一个格子
                for (int cellNum=0; cellNum<cellCount; cellNum++) {
                    // 获取到的cell就是第一行的每一个格子
                    Cell cell = rowData.getCell(cellNum);
                    if (cell != null) {
                        //getCellType判断每一行的每一个格子的数据类型。类型被poi官方封装成了枚举类，里面用数字表示类型。可以点击getCellType看看源码
                        int cellType = cell.getCellType();
                        String cellValue = ""; //格子里面的具体数据
                        switch (cellType) {
                            case XSSFCell.CELL_TYPE_STRING://如果是字符串
                                cellValue = cell.getStringCellValue();//getStringCellValue方法只能获取字符串数据
                                break;
                            case XSSFCell.CELL_TYPE_BOOLEAN://如果是布尔值
                                cellValue = String.valueOf(cell.getBooleanCellValue());//getBooleanCellValue方法只能获取布尔值数据
                                break;
                            case XSSFCell.CELL_TYPE_NUMERIC://如果是数字(包括日期、普通数字)
                                if (HSSFDateUtil.isCellDateFormatted(cell)){ //如果是日期
                                    cellValue = new DateTime(cell.getDateCellValue()).toString("yyyy-MM-dd");//getStringCellValue方法只能获取日期数据
                                }else {
                                    cell.setCellType(XSSFCell.CELL_TYPE_STRING);//注意数字类型要转换成字符串类型，才能输出，避免数字过长
                                    cellValue = cell.toString();
                                }
                                break;
                            case XSSFCell.CELL_TYPE_ERROR://如果表格里的数据类型不对
                                throw new RuntimeException("表格里的数据类型不对");
                        }
                        //输出这些格子的数据
                        System.out.print(cellValue + " | ");
                    }
                }
                System.out.println();
            }
        }
        fileInputStream.close();
    }
}
